package com.xbai.canal.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.xbai.content.feign.ContentFeign;
import com.xbai.content.pojo.Content;
import com.xbai.entity.Result;
import com.xbai.item.feign.PageFeign;
import com.xpand.starter.canal.annotation.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;

/**
 * @author jxbai
 * @desc 实现对表增删改操作的监听
 * CanalEventListener 事件监听的注解 监听数据库的变化
 * @date 2021/1/29
 */
@CanalEventListener
@Slf4j
@RequiredArgsConstructor
public class CanalDataEventListener {

    private final ContentFeign contentFeign;

    private final PageFeign pageFeign;

    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 增加数据监听
     *
     * @param eventType {@link CanalEntry.EventType}
     * @param rowData   {@link CanalEntry.RowData}
     */
    @InsertListenPoint
    public void onEventInsert(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        rowData.getAfterColumnsList().forEach(c -> {
            log.info("InsertListenPoint By--Annotation: {} : {}", c.getName(), c.getValue());
        });
    }

    /**
     * 修改数据监听
     *
     * @param eventType {@link CanalEntry.EventType}
     * @param rowData   {@link CanalEntry.RowData}
     */
    @UpdateListenPoint
    public void onEventUpdate(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        rowData.getAfterColumnsList().forEach(c -> {
            log.info("UpdateListenPoint By--Annotation: {} : {}", c.getName(), c.getValue());
        });
    }

    /**
     * 修改数据监听
     *
     * @param eventType {@link CanalEntry.EventType}
     * @param rowData   {@link CanalEntry.RowData}
     */
    @DeleteListenPoint
    public void onEventDelete(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        rowData.getAfterColumnsList().forEach(c -> {
            log.info("DeleteListenPoint By--Annotation: {} : {}", c.getName(), c.getValue());
        });
    }

    /**
     * 自定义数据修改监听
     *
     * @param eventType {@link CanalEntry.EventType}
     * @param rowData   {@link CanalEntry.RowData}
     */
    @ListenPoint(destination = "example",
            schema = "changgou_content",
            table = {"tb_content_category", "tb_content"},
            eventType = {CanalEntry.EventType.UPDATE,
                    CanalEntry.EventType.DELETE,
                    CanalEntry.EventType.INSERT})
    public void onEventCustomUpdate(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        // 1.获取到被修改的 category id
        String categoryId = getColumnValue(eventType, rowData);

        // 2.调用feign 获取数据
        Result<List<Content>> result = contentFeign.findByCategory(Long.valueOf(categoryId));

        // 3.存储到 Redis 中
        List<Content> data = result.getData();
        stringRedisTemplate.boundValueOps("content_" + categoryId).set(JSON.toJSONString(data));
    }

    private String getColumnValue(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        //1.判断更改类型 如果是删除 则需要获取到before的数据
        String categoryId = "";
        if (CanalEntry.EventType.DELETE == eventType) {
            for (CanalEntry.Column column : rowData.getBeforeColumnsList()) {
                //column.getName(列的名称   column.getValue() 列对应的值
                if ("category_id".equals(column.getName())) {
                    categoryId = column.getValue();
                    return categoryId;
                }
            }
        } else {
            //2判断是 更新 新增 获取after的数据
            for (CanalEntry.Column column : rowData.getAfterColumnsList()) {
                if ("category_id".equals(column.getName())) {
                    categoryId = column.getValue();
                    return categoryId;
                }
            }
        }
        return categoryId;
    }

    /**
     * 监听商品数据库的spu的表的数据的变化,变了,调用feign 生成静态页就可以了
     * @param eventType {@link CanalEntry.EventType}
     * @param rowData {@link CanalEntry.RowData}
     */
    @ListenPoint(destination = "example",
            schema = "changgou_goods",
            table = {"tb_spu"},
            eventType = {CanalEntry.EventType.UPDATE,
                    CanalEntry.EventType.DELETE,
                    CanalEntry.EventType.INSERT})
    public void onEventCustomSpu(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        //判断更改类型
        if (CanalEntry.EventType.DELETE == eventType) {
            String spuId = "";
            for (CanalEntry.Column column : rowData.getBeforeColumnsList()) {
                //column.getName(列的名称   column.getValue() 列对应的值
                if ("id".equals(column.getName())) {
                    spuId = column.getValue();
                    break;
                }
            }
            //todo 删除静态页
        } else {
            //新增 或者 更新
            String spuId = "";
            for (CanalEntry.Column column : rowData.getAfterColumnsList()) {
                if ("id".equals(column.getName())) {
                    spuId = column.getValue();
                    break;
                }
            }
            //更新 生成静态页
            pageFeign.createHtml(Long.parseLong(spuId));
        }
    }

}
